package com.lanvideo.service;

import com.lanvideo.dao.ExamDao;
import com.lanvideo.dao.ExamQuestionDao;
import com.lanvideo.dao.ExamStudentDao;
import com.lanvideo.dao.QuestionDao;
import com.lanvideo.dao.ExamAnswerDao;
import com.lanvideo.dao.ExamRecordDao;
import com.lanvideo.entity.Exam;
import com.lanvideo.entity.ExamQuestion;
import com.lanvideo.entity.ExamStudent;
import com.lanvideo.entity.Question;
import com.lanvideo.entity.ExamAnswer;
import com.lanvideo.entity.ExamRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.Collections;
import java.time.LocalDateTime;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 考试服务类
 */
@Service
public class ExamService {
    
    @Autowired
    private ExamDao examDao;
    
    @Autowired
    private ExamQuestionDao examQuestionDao;
    
    @Autowired
    private ExamStudentDao examStudentDao;
    
    @Autowired
    private QuestionDao questionDao;
    
    @Autowired
    private ExamAnswerDao examAnswerDao;
    
    @Autowired
    private ExamRecordDao examRecordDao;
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    // 考试锁映射，确保同一考试的并发操作安全
    private final ConcurrentHashMap<Integer, ReentrantLock> examLocks = new ConcurrentHashMap<>();
    
    // 学生考试锁映射，确保同一学生同一考试的并发操作安全
    private final ConcurrentHashMap<String, ReentrantLock> studentExamLocks = new ConcurrentHashMap<>();

    /**
     * 获取考试锁
     */
    private ReentrantLock getExamLock(Integer examId) {
        return examLocks.computeIfAbsent(examId, k -> new ReentrantLock());
    }

    /**
     * 获取学生考试锁
     */
    private ReentrantLock getStudentExamLock(Integer examId, Integer studentId) {
        String key = examId + "_" + studentId;
        return studentExamLocks.computeIfAbsent(key, k -> new ReentrantLock());
    }

    /**
     * 创建考试
     */
    public boolean createExam(Exam exam) {
        try {
            // 设置默认值
            if (exam.getTotalQuestions() == null) {
                exam.setTotalQuestions(0);
            }
            if (exam.getTotalScore() == null) {
                exam.setTotalScore(0);
            }
            if (exam.getStatus() == null) {
                exam.setStatus(0); // 默认状态为草稿
            }
            
            examDao.createExam(exam);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 更新考试
     */
    public boolean updateExam(Exam exam) {
        try {
            examDao.updateExam(exam);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除考试
     */
    public boolean deleteExam(Integer examId) {
        try {
            examDao.deleteExam(examId);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取考试详情
     */
    public Exam getExamById(Integer examId) {
        return examDao.getExamById(examId);
    }

    /**
     * 获取老师创建的所有考试
     */
    public List<Exam> getExamsByTeacherId(Integer teacherId) {
        return examDao.getExamsByTeacherId(teacherId);
    }

    /**
     * 获取学生可参与的考试
     */
    public List<Exam> getAvailableExamsForStudent(Integer studentId) {
        return examDao.getAvailableExamsForStudent(studentId);
    }

    /**
     * 获取所有考试（管理员）
     */
    public List<Exam> getAllExams() {
        return examDao.getAllExams();
    }

    /**
     * 发布考试
     */
    public boolean publishExam(Integer examId) {
        try {
            examDao.updateExamStatus(examId, 1);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 结束考试
     */
    public boolean endExam(Integer examId) {
        try {
            examDao.updateExamStatus(examId, 2);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 添加题目到考试
     */
    public boolean addQuestionToExam(Integer examId, Integer questionId) {
        try {
            examQuestionDao.addQuestionToExam(examId, questionId);
            
            // 更新考试题目数量和总分
            updateExamQuestionCount(examId);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 从考试中移除题目
     */
    public boolean removeQuestionFromExam(Integer examId, Integer questionId) {
        try {
            examQuestionDao.removeQuestionFromExam(examId, questionId);
            updateExamQuestionCount(examId);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取考试的所有题目
     */
    public List<ExamQuestion> getExamQuestions(Integer examId) {
        return examQuestionDao.getExamQuestions(examId);
    }

    /**
     * 更新考试题目数量
     */
    private void updateExamQuestionCount(Integer examId) {
        try {
            int questionCount = examQuestionDao.getExamQuestionCount(examId);
            Exam exam = examDao.getExamById(examId);
            if (exam != null) {
                exam.setTotalQuestions(questionCount);
                exam.setTotalScore(questionCount * 10); // 每题10分
                examDao.updateExam(exam);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 添加学生到考试
     */
    public boolean addStudentToExam(Integer examId, Integer studentId) {
        try {
            if (!examStudentDao.isStudentInExam(examId, studentId)) {
                examStudentDao.addStudentToExam(examId, studentId);
                return true;
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 批量添加学生到考试
     */
    public boolean addStudentsToExam(Integer examId, List<Integer> studentIds) {
        try {
            examStudentDao.addStudentsToExam(examId, studentIds);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 从考试中移除学生
     */
    public boolean removeStudentFromExam(Integer examId, Integer studentId) {
        try {
            examStudentDao.removeStudentFromExam(examId, studentId);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取考试的所有学生
     */
    public List<ExamStudent> getExamStudents(Integer examId) {
        return examStudentDao.getExamStudents(examId);
    }

    /**
     * 获取学生参与的考试
     */
    public List<ExamStudent> getStudentExams(Integer studentId) {
        return examStudentDao.getStudentExams(studentId);
    }

    /**
     * 开始考试（并发安全）
     */
    public boolean startExam(Integer examId, Integer studentId) {
        ReentrantLock lock = getStudentExamLock(examId, studentId);
        lock.lock();
        try {
            // 检查学生是否已经开始了考试
            ExamStudent examStudent = examStudentDao.getStudentExamStatus(examId, studentId);
            if (examStudent != null && examStudent.getStatus() == 1) {
                return true; // 已经开始了考试，允许继续
            }
            
            // 如果学生还没有被添加到考试中，先添加
            if (examStudent == null) {
                int addResult = examStudentDao.addStudentToExam(examId, studentId);
                if (addResult <= 0) {
                    return false;
                }
            }
            
            // 开始考试
            int startResult = examStudentDao.startExam(examId, studentId);
            if (startResult <= 0) {
                return false;
            }
            
            return true;
        } catch (Exception e) {
            return false;
        } finally {
            lock.unlock();
        }
    }

    /**
     * 完成考试（并发安全）
     */
    public boolean completeExam(Integer examId, Integer studentId, Integer score) {
        ReentrantLock lock = getStudentExamLock(examId, studentId);
        lock.lock();
        try {
            // 检查学生是否已经完成了考试
            ExamStudent examStudent = examStudentDao.getStudentExamStatus(examId, studentId);
            if (examStudent != null && examStudent.getStatus() == 2) {
                return false; // 已经完成了考试
            }
            
            examStudentDao.completeExam(examId, studentId, score);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            lock.unlock();
        }
    }

    /**
     * 获取学生考试状态
     */
    public ExamStudent getStudentExamStatus(Integer examId, Integer studentId) {
        return examStudentDao.getStudentExamStatus(examId, studentId);
    }

    /**
     * 获取所有题目（用于选择）
     */
    public List<Question> getAllQuestions() {
        return questionDao.findAll();
    }

    /**
     * 获取未添加到考试的题目
     */
    public List<Question> getAvailableQuestions(Integer examId) {
        List<Question> allQuestions = questionDao.findAll();
        List<ExamQuestion> examQuestions = examQuestionDao.getExamQuestions(examId);
        
        // 过滤掉已添加的题目
        for (ExamQuestion eq : examQuestions) {
            allQuestions.removeIf(q -> q.getId().equals(eq.getQuestionId()));
        }
        
        return allQuestions;
    }

    /**
     * 创建新题目
     */
    public boolean createQuestion(Question question) {
        try {
            return questionDao.createQuestion(question);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 更新题目
     */
    public boolean updateQuestion(Question question) {
        try {
            return questionDao.updateQuestion(question);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除题目
     */
    public boolean deleteQuestion(Integer questionId) {
        try {
            System.out.println("ExamService.deleteQuestion 开始删除题目ID: " + questionId);
            boolean result = questionDao.deleteQuestion(questionId);
            System.out.println("ExamService.deleteQuestion 删除结果: " + result);
            return result;
        } catch (Exception e) {
            System.err.println("ExamService.deleteQuestion 删除失败: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据ID获取题目
     */
    public Question getQuestionById(Integer questionId) {
        try {
            return questionDao.getQuestionById(questionId);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取学生可参加的考试列表
     */
    public List<Exam> getAvailableExams() {
        return examDao.getPublishedExams();
    }

    /**
     * 检查学生是否已经参加过考试
     */
    public boolean hasStudentTakenExam(Integer examId, Integer studentId) {
        return examStudentDao.hasStudentTakenExam(examId, studentId);
    }

    /**
     * 从老师已添加的题目中随机选择考试题目
     */
    public List<Question> generateRandomQuestions(Integer examId) {
        Exam exam = examDao.getExamById(examId);
        if (exam == null) {
            return new ArrayList<>();
        }
        
        
        // 获取老师已经添加到这个考试的所有题目
        List<ExamQuestion> examQuestions = examQuestionDao.getExamQuestions(examId);
        
        if (examQuestions.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 获取应考题目数量
        Integer questionCount = exam.getExamQuestions();
        if (questionCount == null || questionCount <= 0) {
            // 如果没有设置应考题目数量，则使用 totalQuestions 字段
            questionCount = exam.getTotalQuestions();
            if (questionCount == null || questionCount <= 0) {
                // 如果还是没有，则使用老师添加的所有题目
                questionCount = examQuestions.size();
            }
        }
        
        
        // 从老师已添加的题目中随机选择指定数量的题目
        List<Question> selectedQuestions = new ArrayList<>();
        List<ExamQuestion> shuffledExamQuestions = new ArrayList<>(examQuestions);
        Collections.shuffle(shuffledExamQuestions); // 随机打乱顺序
        
        int selectCount = Math.min(questionCount, examQuestions.size());
        for (int i = 0; i < selectCount; i++) {
            ExamQuestion examQuestion = shuffledExamQuestions.get(i);
            Question question = questionDao.getQuestionById(examQuestion.getQuestionId());
            if (question != null) {
                selectedQuestions.add(question);
            }
        }
        
        
        
        return selectedQuestions;
    }
    

    /**
     * 保存考试题目
     */
    public void saveExamQuestions(Integer examId, List<Question> questions) {
        for (int i = 0; i < questions.size(); i++) {
            // 直接调用 addQuestionToExam 方法，它只接受 examId 和 questionId
            examQuestionDao.addQuestionToExam(examId, questions.get(i).getId());
        }
    }

    /**
     * 提交考试答案并计算成绩
     */
    public ExamRecord submitExamAnswers(Integer examId, Integer studentId, Map<String, String> answers) {
        ReentrantLock lock = getStudentExamLock(examId, studentId);
        lock.lock();
        try {
            // 调试日志
            System.out.println("=== ExamService.submitExamAnswers Debug ===");
            System.out.println("Exam ID: " + examId + ", Student ID: " + studentId);
            System.out.println("Answers received: " + answers);
            
            // 获取考试题目
            List<ExamQuestion> examQuestions = examQuestionDao.getExamQuestions(examId);
            if (examQuestions.isEmpty()) {
                throw new RuntimeException("考试题目不存在");
            }
            
            int correctCount = 0;
            int totalQuestions = examQuestions.size();
            
            // 保存答题记录并计算成绩
            for (ExamQuestion examQuestion : examQuestions) {
                String questionId = examQuestion.getQuestionId().toString();
                String studentAnswer = answers.get(questionId);
                if (studentAnswer == null) {
                    studentAnswer = ""; // 未答题
                }
                
                System.out.println("Processing Question ID: " + questionId + ", Student Answer: '" + studentAnswer + "'");
                
                // 获取正确答案
                Question question = questionDao.getQuestionById(examQuestion.getQuestionId());
                if (question != null) {
                    boolean isCorrect = studentAnswer.equals(question.getCorrectAns());
                    if (isCorrect) {
                        correctCount++;
                    }
                    
                    System.out.println("Question: " + question.getContent() + ", Correct Answer: '" + question.getCorrectAns() + "', Is Correct: " + isCorrect);
                    
                    // 保存答题记录
                    ExamAnswer answer = new ExamAnswer(examId, studentId, examQuestion.getQuestionId(), 
                            studentAnswer, question.getCorrectAns());
                    int saveResult = examAnswerDao.saveAnswer(answer);
                    System.out.println("Save result: " + saveResult);
                }
            }
            
            // 创建考试记录
            ExamRecord record = new ExamRecord();
            record.setExamId(examId);
            record.setStudentId(studentId);
            record.setScore(correctCount);
            record.setTotalQuestions(totalQuestions);
            record.setExamTime(LocalDateTime.now());
            
            // 保存考试记录
            examRecordDao.addExamRecord(record);
            
            // 更新考试学生状态为已完成
            examStudentDao.completeExam(examId, studentId, correctCount);
            
            return record;
        } finally {
            lock.unlock();
        }
    }

    /**
     * 获取学生的考试记录
     */
    public List<ExamRecord> getStudentExamRecords(Integer studentId) {
        return examRecordDao.getStudentExamRecords(studentId);
    }

    /**
     * 获取学生的考试答题记录
     */
    public List<ExamAnswer> getStudentExamAnswers(Integer examId, Integer studentId) {
        return examAnswerDao.getStudentExamAnswers(examId, studentId);
    }

    /**
     * 获取学生的特定考试记录
     */
    public ExamRecord getStudentExamRecord(Integer examId, Integer studentId) {
        return examRecordDao.getStudentExamRecord(examId, studentId);
    }

    /**
     * 获取考试的所有答题记录
     */
    public List<ExamAnswer> getExamAllAnswers(Integer examId) {
        return examAnswerDao.getExamAnswers(examId);
    }

    /**
     * 获取考试的所有记录
     */
    public List<ExamRecord> getExamRecords(Integer examId) {
        return examRecordDao.getExamRecords(examId);
    }

    /**
     * 获取老师的考试列表
     */
    public List<Exam> getTeacherExams(Integer teacherId) {
        return examDao.getTeacherExams(teacherId);
    }


    /**
     * 取消发布考试
     */
    public boolean unpublishExam(Integer examId) {
        return examDao.updateExamStatus(examId, 0) > 0;
    }

    /**
     * 更新考试应考题目数量
     */
    public boolean updateExamQuestions(Integer examId, Integer examQuestions) {
        try {
            // 使用现有的 total_questions 字段来存储应考题目数量
            String sql = "UPDATE exam SET total_questions=? WHERE id=?";
            int result = jdbcTemplate.update(sql, examQuestions, examId);
            return result > 0;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    // 自动保存答案
    public boolean autoSaveExamAnswers(Integer examId, Integer studentId, Map<String, String> answers) {
        try {
            System.out.println("=== ExamService.autoSaveExamAnswers 调试 ===");
            System.out.println("考试ID: " + examId);
            System.out.println("学生ID: " + studentId);
            System.out.println("答案数量: " + answers.size());
            
            // 获取考试题目
            List<ExamQuestion> examQuestions = examQuestionDao.getExamQuestions(examId);
            System.out.println("考试题目数量: " + examQuestions.size());
            
            // 保存每个答案
            for (Map.Entry<String, String> entry : answers.entrySet()) {
                Integer questionId = Integer.parseInt(entry.getKey());
                String studentAnswer = entry.getValue();
                
                System.out.println("处理题目ID: " + questionId + ", 学生答案: " + studentAnswer);
                
                // 检查是否已存在答案记录
                List<ExamAnswer> existingAnswers = examAnswerDao.getStudentExamAnswers(examId, studentId);
                ExamAnswer existingAnswer = null;
                for (ExamAnswer answer : existingAnswers) {
                    if (answer.getQuestionId().equals(questionId)) {
                        existingAnswer = answer;
                        break;
                    }
                }
                
                if (existingAnswer != null) {
                    // 更新现有答案
                    existingAnswer.setStudentAnswer(studentAnswer);
                    int updateResult = examAnswerDao.saveAnswer(existingAnswer);
                    System.out.println("更新答案结果: " + (updateResult > 0));
                } else {
                    // 创建新答案记录
                    ExamAnswer newAnswer = new ExamAnswer();
                    newAnswer.setExamId(examId);
                    newAnswer.setStudentId(studentId);
                    newAnswer.setQuestionId(questionId);
                    newAnswer.setStudentAnswer(studentAnswer);
                    
                    // 获取正确答案
                    Question question = questionDao.findById(questionId);
                    if (question != null) {
                        newAnswer.setCorrectAnswer(question.getCorrectAns());
                    }
                    
                    int insertResult = examAnswerDao.saveAnswer(newAnswer);
                    System.out.println("插入答案结果: " + (insertResult > 0));
                }
            }
            
            System.out.println("=== 自动保存完成 ===");
            return true;
            
        } catch (Exception e) {
            System.out.println("自动保存异常: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }
}